<Html>
    <head>
        <title>值对象 Value Object</title>
    </head>
    <body>
        <script>
            //  价值对象

                /*
                    "一个对象，这个对象表示的是对领域内容的描述，而且这个对象没有概念标识，那这个对象就是"值对象""

                    具有相同属性但具有不同Ids的两个实体被视为不同的实体。但是，值对象没有Ids，如果它们具有相同的属性值，则它们被视为相等。
                */

                /*
                    一、值对象类   ValueObject



                            1、如何声明值对象类

                                        ValueObject是一个抽象类，可以继承以创建Value Object类。

                                            eg:
                                                // 声明一个值对象类
                                                public class Address : ValueObject
                                                {
                                                    public Guid CityId { get; private set; }

                                                    public string Street { get; private set; }

                                                    public int Number { get; private set; }

                                                    private Address()
                                                    {
                                                        
                                                    }
                                                    
                                                    public Address(
                                                        Guid cityId,
                                                        string street,
                                                        int number)
                                                    {
                                                        CityId = cityId;
                                                        Street = street;
                                                        Number = number;
                                                    }

                                                    // 必须实现此方法，一返回原始值
                                                    protected override IEnumerable<object> GetAtomicValues()
                                                    {
                                                        yield return Street;
                                                        yield return CityId;
                                                        yield return Number;  // yield 返回枚举器，用于迭代集合中的每个元素。

                                                    }
                                                }

                                        Value Object类必须实现GetAtomicValues()方法以返回原始值。


                            2、ValueEquals 方法

                                        ValueObject.ValueEquals(...)方法用于检查两个值对象是否相等。

                                        eg:  检查两个地址是否相等

                                            Address address1 = ...
                                            Address address2 = ...

                                            if (address1.ValueEquals(address2)) //Check equality
                                            {
                                                ...
                                            }

                */

                /*
                    三、最佳实践

                            以下是使用值对象时的一些最佳实践：

                                  如果没有充分的理由将值对象设计为可变的，则将其设计为不可变的（如上面的地址）。   
                                  
                                  构成值对象的属性应该形成一个概念整体。例如，CityId、Street和Number不应该是Person实体的单独属性。这也使Person实体更简单。
                */

        </script>
    </body>
</Html>